package com.lanhao.aot.iot;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.google.common.collect.Maps;

import cn.hutool.http.HttpRequest;

public class IOTCloudUtil {
	public static final String PROTOCOL = "https://";
	public static final String HOST = "linkapi.xf-yun.com";
	public static final String API_KEY = "4C0531502B03473CAEAA4EE15B58512E";
	public static final String API_SECRET = "8Gs1wHXyxLNOwdakisDC9VapWj0MJYxG";
	public static final String ADD_ACTIVE_DEVICE_PATH = "/api/v1/devices/createActive";
	public static final String ContentType = "application/json";
	public static final String SUB_DEVICES_PATH = "/api/v1/topo";
	public static final String DEVICE_PROPERTIES_PATH = "/api/v1/data/device/property";

	/**
	 * 入口
	 *
	 * @param args args
	 */
	public static void main(String[] args) {
//		JSONObject data = new JSONObject();
//		data.put("productKey", "62cfedfb01f8");
//		data.put("deviceName", "TEST_DEVICE_MC_587417741");
//		String postResult = post(data.toJSONString(), ADD_ACTIVE_DEVICE_PATH);
//		System.out.println("POST结果postResult=" + postResult);
		
//		HashMap<String, Object> formMap = Maps.newHashMap();
//		formMap.put("productKey", "dbdbe82e98fd");
//		formMap.put("deviceName", "MAIN_2418C69FE583");
//		String getResult = get(SUB_DEVICES_PATH, formMap);
//		System.out.println("GET结果result=" + getResult);
		
		HashMap<String, Object> formMap = Maps.newHashMap();
		formMap.put("productKey", "61a82b13454e");
		formMap.put("deviceName", "SOCKET_2CD26B682412_2");
		String getResult = get(DEVICE_PROPERTIES_PATH, formMap);
		System.out.println("GET结果result=" + getResult);
	}

	/**
	 * 获取当前时间
	 *
	 * @return 当前时间
	 */
	private static String getCurrentUTCTime() {
		Calendar cd = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'UTC'", Locale.US);
		sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
		return sdf.format(cd.getTime());
	}

	/**
	 * hmac sha256
	 *
	 * @param message 消息
	 * @param secret  密钥
	 * @return hmac sha256结果
	 */
	private static String hmacSHA256(String message, String secret) {
		String hash = "";
		try {
			Mac hmacSha256 = Mac.getInstance("HmacSHA256");
			SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
			hmacSha256.init(secretKey);
			byte[] bytes = hmacSha256.doFinal(message.getBytes());
			hash = Base64.getEncoder().encodeToString(bytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return hash;
	}

	/**
	 * sha256
	 *
	 * @param str 输入
	 * @return sha256结果
	 */
	private static String getSHA256(String str) {
		MessageDigest messageDigest;
		String encodeStr = null;
		try {
			messageDigest = MessageDigest.getInstance("SHA-256");
			messageDigest.update(str.getBytes());
			encodeStr = Base64.getEncoder().encodeToString(messageDigest.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return encodeStr;
	}

	public static String post(String requestBody, String url) {
		String dateStr = getCurrentUTCTime();
		String digestBody = "SHA-256=" + getSHA256(requestBody);
		String requestLine = "POST " + url + " HTTP/1.1";
		String rawSignStr = "host: " + HOST + "\n" + "date: " + dateStr + "\n" + requestLine;
		String digest = hmacSHA256(rawSignStr, API_SECRET);
		String authValue = String.format("hmac username=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"",
				API_KEY, "hmac-sha256", "host date request-line", digest);

		Map<String, String> headers = new HashMap<>();
		headers.put("Content-Type", ContentType);
		headers.put("Host", HOST);
		headers.put("Date", dateStr);
		headers.put("Digest", digestBody);
		headers.put("Authorization", authValue);

		String requestUrl = PROTOCOL + HOST + url;
		String result = HttpRequest.post(requestUrl).addHeaders(headers).body(requestBody).execute().body();

		System.out.println("请求URL=" + requestUrl + ", 请求结果result=" + result);

		return result;
	}

	public static String get(String url, Map<String, Object> formMap) {
		String dateStr = getCurrentUTCTime();
		String requestLine = "GET " + url + " HTTP/1.1";
		String rawSignStr = "host: " + HOST + "\n" + "date: " + dateStr + "\n" + requestLine;
		String digest = hmacSHA256(rawSignStr, API_SECRET);
		String authValue = String.format("hmac username=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"",
				API_KEY, "hmac-sha256", "host date request-line", digest);

		Map<String, String> headers = new HashMap<>();
		headers.put("Content-Type", ContentType);
		headers.put("Host", HOST);
		headers.put("Date", dateStr);
		headers.put("Authorization", authValue);

		String requestUrl = PROTOCOL + HOST + url;
		String result = HttpRequest.get(requestUrl).addHeaders(headers).form(formMap).execute().body();

		System.out.println("请求URL=" + requestUrl + ", 请求结果result=" + result);

		return result;
	}
}
